import math

from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Subquery, OuterRef
from django.shortcuts import render
from .models import Catalog
import json
from hashlib import md5

from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import User
from django.http.response import JsonResponse, HttpResponseForbidden, HttpResponse
from django.shortcuts import render, redirect
from user.tasks import send_mail
from user.models import UserInfo
from django_redis import get_redis_connection
from user.models import UserScore, ScoreConfig
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from user.manages import UserScoreManager
from django.contrib.auth import login as auth_login, logout as auth_logout
import os
from django.http import FileResponse, JsonResponse
from django.conf import settings
from user.models import UserScore
from captcha.image import ImageCaptcha, random_color
import string
import random
from io import BytesIO

from user.models import UserInfo
from .models import ResourceCollect

from .models import Resource
from message.models import Fans
from.models import ResourceComment



def upload_res(request):
    """资源上传"""

    if request.method == "GET":
        # 获取所有 资源分类
        catalog_tree = get_catalog_tree()
        return render(request, 'upload.html', context={"catalog_tree": catalog_tree})

    name = request.POST.get("resourceName")
    description = request.POST.get("description")
    tags = request.POST.get("tags")
    category_id = request.POST.get("category")
    score = request.POST.get("score")
    captcha = request.POST.get("captcha")

    # 1 检查验证码是否正确
    # 获取 redis 中的验证码
    redis_key = f'upload:captcha:{request.user.pk}'
    redis_client = get_redis_connection()
    redis_captcha = redis_client.get(redis_key).decode('utf-8')

    if not redis_captcha:
        return JsonResponse({'status': 300, 'msg': '验证码已过期'})

    if captcha.upper() != redis_captcha.upper():
        return JsonResponse({'status': 300, 'msg': '验证码错误'})

    # 删除 redis 中的验证码
    redis_client.delete(redis_key)

    # 获取 资源id
    resource_id = request.session.get('resource')

    try:
        # 2 上传资源 更新 资源明细
        Resource.objects.filter(pk=resource_id).update(name=name, desc=description, keyword=tags,
                                                       classify_id=category_id,
                                                       score=score)
    except Exception as e:
        return JsonResponse(data={'code': 500, 'msg': '上传失败，请稍后重试'})

    # 3  赠送积分
    UserScore.objects.create_score('上传资源', user_id=request.user.pk, remark="上传资源",
                                   res_id=resource_id)

    return JsonResponse(data={'code': 200, 'msg': '上传成功', 'res_id': resource_id})


def get_catalog_tree():
    """获取分类树形结构"""
    # 获取所有顶层 分类
    top_level_catalogs = Catalog.objects.filter(parent__isnull=True, is_delete=False)

    # 存放[{'catalog': catalog, 'children': [...]}, ...]
    catalog_tree = []

    for catalog in top_level_catalogs:
        # 获取对应的 子分类
        children = Catalog.objects.filter(parent_id=catalog.pk, is_delete=False)
        child_list = [child for child in children]
        catalog_tree.append({
            'catalog': catalog,
            'children': child_list
        })

    return catalog_tree


def upload_file(request):
    """文件上传"""

    file = request.FILES.get('document')
    ext = request.POST.get('ext')
    size = request.POST.get('size')
    uid = request.user.pk

    size = math.ceil(int(size) / 1024 / 1024)  # 转换为 MB

    # 判断用户是否存在
    if not User.objects.filter(id=uid).exists():
        return JsonResponse(data={'code': 403, 'msg': '用户不存在'})

    # 保存资源
    res = Resource.objects.create(path=file, ext=ext, size=size, user_id=uid)

    # 将资源id 存储到 session 在更新 资源信息时使用
    request.session['resource'] = res.pk

    return JsonResponse(data={'code': 200, 'msg': '上传成功'})


def captcha(request):
    """
    生成验证码
    """
    width = int(request.GET.get('w'))
    height = int(request.GET.get('h'))

    # 创建 验证码对象, 随机字体大小
    captcha = ImageCaptcha(width=width, height=height, font_sizes=[29, 28, 26])

    # 生成随机4 位长度 验证码
    captcha_array = random.choices(string.ascii_uppercase + string.digits, k=4)
    captcha_text = ''.join(captcha_array)
    print(captcha_text)

    # 生成 验证码图片
    image = captcha.create_captcha_image(captcha_text, color=(255, 50, 20), background=(255, 255, 255))

    # 给图片 添加干扰线
    captcha.create_noise_curve(image, color=random_color(100, 200))
    # 给图片 添加干扰点
    captcha.create_noise_dots(image, color=random_color(50, 100), number=20)

    # 将验证码 存储到 redis中
    redis_key = f'upload:captcha:{request.user.pk}'
    redis_client = get_redis_connection()
    redis_client.setex(redis_key,300 ,captcha_text)  # 5分钟过期

    # 将图片 写入到相应对象中
    out = BytesIO()  # 流对象
    image.save(out, 'png')
    # 流 读取的位置 指向 0
    out.seek(0)
    return HttpResponse(out.read(), content_type='image/png')


def detail(request, res_id):
    """资源详情"""

    try:
        res = Resource.objects.get(pk=res_id, is_delete=False)
    except Resource.DoesNotExist:
        return HttpResponse("资源不存在或已被删除")

    # 资源上传者 信息
    uploader_id = res.user_id
    uploader = UserInfo.objects.get(user_id=uploader_id)

    res.keyword = res.keyword.split(',')

    #是否关注
    if Fans.objects.filter(fans_id=request.user.id,user_id=uploader_id).exists():
        attention='已关注'
    elif Fans.objects.filter(fans_id=uploader_id,user_id=request.user.id,is_mutual=True).exists():
        attention = '已关注'
    else:
        attention = '关注'

    #所有评论
    comments=ResourceComment.objects.filter(resource_id=res.pk,state='1')


    return render(request, 'detail.html', context=
    {'res': res, 'uploader': uploader,'attention':attention,'comments':comments})

def attention(request):
    """关注用户"""
    #匿名用户去登录
    if not request.user.is_authenticated:
        return JsonResponse({'code':401,'msg':'请先登录'})


    #资源id
    res_id=request.POST.get('res_id')
    #被关注 用户id 资源所有者
    user_id=Resource.objects.filter(pk=res_id).first().user_id
    #当前用户id
    current_id=request.user.id

    #不能关注自己
    if user_id==current_id:
        return JsonResponse({'code':400,'msg':'不能关注自己'})

    #判断是否已关注



    # 如果已关注，则取消关注（删除我→对方的记录，并将对方→我的记录的互关标记取消）
    if Fans.objects.filter(fans_id=current_id, user_id=user_id).exists():
        # 删除我→对方的关注记录
        Fans.objects.filter(fans_id=current_id, user_id=user_id).delete()
        # 取消对方→我的互关标记（如果存在）
        Fans.objects.filter(fans_id=user_id, user_id=current_id).update(is_mutual=False)
        return JsonResponse({'code': 200, 'msg': '已取消关注'})

    # 如果未关注，但对方已关注我：则我关注对方，同时标记为互关
    if Fans.objects.filter(fans_id=user_id, user_id=current_id).exists():
        # 创建我→对方的关注记录
        Fans.objects.create(fans_id=current_id, user_id=user_id)
        # 将对方→我的记录标记为互关
        Fans.objects.filter(fans_id=user_id, user_id=current_id).update(is_mutual=True)
        return JsonResponse({'code': 200, 'msg': '已互关'})

    # 未关注且对方也未关注我：单纯关注
    Fans.objects.create(fans_id=current_id, user_id=user_id)
    return JsonResponse({'code': 200, 'msg': '关注成功'})



def comment(request):
    """资源评论"""
    res_id=request.POST.get('res_id')
    content=request.POST.get('content')
    start=request.POST.get('star')

    try:
        ResourceComment.objects.create(resource_id=res_id,user_id=request.user.id,content=content,star=start,state='1')
    except Exception as e:
        return JsonResponse({'code': 400, 'msg': '评论失败'})
    return JsonResponse({'code':200,'msg':'发表评论成功'})



def download_res(request, res_id):
    """资源下载"""
    return HttpResponse("资源下载功能正在维护中，敬请期待！")



def upload_res(request):
    if request.method == 'GET':
        return render(request, 'upload.html')

def collect_list(request):
    """收藏列表"""
    if not request.user.is_authenticated:
        return redirect('login')

    user = request.user
    # 获取 用户收藏的资源
    collects = ResourceCollect.objects.filter(user_id=user.pk).all()
    # 获取 资源的详细信息
    resources = Resource.objects.filter(pk__in=[c.resource_id for c in collects], is_delete=False)

    #用户信息
    userInfo=UserInfo.objects.filter(user_id=user.pk).first()
    print(userInfo.avtar)


    return render(request, 'shoucang.html', context={'resources': resources,'user':user,'userInfo':userInfo})


def collect(request):
    """资源收藏"""
    if request.method != "POST":
        return HttpResponseForbidden("仅支持POST请求")

    res_id = request.POST.get('res_id')
    user = request.user

    if not Resource.objects.get(pk=res_id, is_delete=False):
        return JsonResponse({'code': 404, 'msg': '资源不存在或已被删除'})

    # 取消收藏
    if ResourceCollect.objects.filter(resource_id=res_id, user_id=user.pk).exists():
        ResourceCollect.objects.filter(resource_id=res_id, user_id=user.pk).delete()
        return JsonResponse({'code': 200, 'msg': '已取消收藏'})
    # 收藏资源
    ResourceCollect.objects.create(resource_id=res_id, user_id=user.pk)
    return JsonResponse({'code': 200, 'msg': '收藏成功'})
